<template>
  <div id="cesiumContainer"></div>
</template>

<script lang="ts" setup>
//最好先去下载个插件 https://github.com/nshen/vite-plugin-cesium
import { onMounted, reactive } from "vue";
import * as Cesium from "cesium";
import ChinaJson from "@/assets/json/china.json";
import ic_point from "@/assets/img/map/ic_point.png";
import tilesJson from "@/assets/json/3dtile.json";
interface BasePoint {
  id: string;
  lng: string;
  lat: string;
  name: string;
}
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0NDZkYTVlYi0zNGJkLTRiZmMtOGQxNC1mMWIzMzk0MWNhY2QiLCJpZCI6MTYzMjQyLCJpYXQiOjE2OTMyOTgyNDF9.yTV83ecGrZi3wBQCFlP8fsFx8VKXT97f7lBSUBzRuTY";
let viewer: Cesium.Viewer;
const pointList = reactive<BasePoint[]>([
  {
    id: "1",
    lng: "104.53",
    lat: "30.05",
    name: "测试点位",
  },
]);
async function initMap() {
  viewer = new Cesium.Viewer("cesiumContainer", {
    homeButton: false, //是否显示返回首页按钮
    sceneModePicker: false, //是否显示投影方式控件
    baseLayerPicker: true, //是否显示图层选择控件
    navigationHelpButton: false, //是否显示帮助信息控件
    geocoder: false, //是否显示地名查找控件
    animation: false, //是否显示动画控件
    timeline: false, //是否显示时间线控件
    fullscreenButton: false,
    vrButton: false,
    shadows: true, //影子
    infoBox: false, //是否显示点击要素之后显示的信息
    terrainProvider: await Cesium.createWorldTerrainAsync(),
  });
  // 隐藏Cesium的logo
  viewer.cesiumWidget.creditContainer.style.display = "none";

  //飞入效果
  // viewer.camera.flyTo({
  //   destination: Cesium.Cartesian3.fromDegrees(110.786552, 23.61798, 100000),
  //   duration: 3, // 飞行所用时间
  //   // 飞行完成后的事件
  //   // complete: function () {
  //   //   viewer.camera.flyTo({});
  //   // },
  // });

  //添加高德的标注信息
  viewer.imageryLayers.addImageryProvider(
    new Cesium.UrlTemplateImageryProvider({
      url: "http://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
    })
  );

  // 加载本地geojson文件
  viewer.dataSources
    .add(
      Cesium.GeoJsonDataSource.load(ChinaJson, {
        clampToGround: true, // 是否贴地
        fill: Cesium.Color.RED.withAlpha(0.1), //填充颜色
      })
    )
    .then((datasource) => {
      viewer.dataSources.add(datasource);
    });

  //注册场景点击事件
  var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.setInputAction(function (e: any) {
    var pick = viewer.scene.pick(e.position);
    if (pick && pick.id.id == "1") {
      console.log("点击到了测试点位", pick);
    }

    //屏幕坐标转世界坐标
    const cartesian = viewer.camera.pickEllipsoid(
      e.position,
      viewer.scene.globe.ellipsoid
    );
    // 将笛卡尔坐标转换为地理坐标，用于展示弹窗
    const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
    // 将弧度转为度的十进制度表示，保留5位小数
    const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
    const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);
    console.log("经度", lon);
    console.log("纬度", lat);
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  add3DTiles();

  //添加wms服务 https://cesium.com/learn/cesiumjs/ref-doc/WebMapServiceImageryProvider.html
  // const imageryLayers = viewer.imageryLayers;
  // imageryLayers.addImageryProvider(
  //   new Cesium.WebMapServiceImageryProvider({
  //     url: "https://nationalmap.gov.au/proxy/http://geoserver.nationalmap.nicta.com.au/geotopo_250k/ows",
  //     layers: "Hydrography:bores",
  //     parameters: {
  //       transparent: true,
  //       format: "image/png",
  //     },
  //   })
  // );
  // 添加wmts服务 https://cesium.com/learn/cesiumjs/ref-doc/WebMapTileServiceImageryProvider.html
  // const provider = new Cesium.WebMapTileServiceImageryProvider({
  //   url: "https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",
  //   layer: "MODIS_Terra_CorrectedReflectance_TrueColor",
  //   style: "default",
  //   tileMatrixSetID: "250m",
  //   maximumLevel: 5,
  //   format: "image/jpeg",
  //   clock: viewer.clock,
  //   credit: "NASA Global Imagery Browse Services for EOSDIS",
  // });
  // const imageryLayers = viewer.imageryLayers;
  // imageryLayers.addImageryProvider(provider);
}
//添加点位信息
function addPoint() {
  //为避免异常，先清空所有实体
  viewer.entities.removeAll();
  pointList.forEach((item: BasePoint) => {
    viewer.entities.add({
      name: item.name,
      type: "point", //自定义属性，可用于判断点击是否为point类型
      id: item.id,
      position: Cesium.Cartesian3.fromDegrees(
        Number(item.lng),
        Number(item.lat)
      ),
      label: {
        // show: false,
        text: item.name, //文本内容
        font: "12px monospace", //字体内容
        style: Cesium.LabelStyle.FILL_AND_OUTLINE, //文本轮廓
        fillColor: Cesium.Color.LIME, //文字填充颜色
        outlineWidth: 4, //外边线宽度
        showBackground: false, //是否显示背景
        backgroundColor: Cesium.Color.fromCssColorString("rgba(52,79,209,1.0)"), //背景墙的颜色
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直方向以底部来计算标签的位置
        pixelOffset: new Cesium.Cartesian2(0, -20), // 偏移量
      },
      // 图标
      billboard: {
        image: ic_point,
        width: 20,
        height: 24,
      },
    });
  });
}
// 添加3DTiles
async function add3DTiles() {
  let longitude = 110.786552; // 3DTiles影像模型中心点经度

  let latitude = 23.61798; // 3DTiles影像模型中心点纬度

  let height = 8; // 3DTiles影像模型高度

  // let url = "http://182.108.159.7:18080/dezhai_3DTiles/tileset.json";  // 3DTiles影像模型地址
  // let url = "https://cdjinyatu.com/dezhai_3DTiles/tileset.json";  // 3DTiles影像模型地址
   let url = "https://ayszgx.com/dezhai_3DTiles/tileset.json"; // 3DTiles影像模型地址
  //tilesJson 可替换成url
  const tileset = await Cesium.Cesium3DTileset.fromUrl(url, {
    dynamicScreenSpaceError: true,
    dynamicScreenSpaceErrorDensity: 0.00278,
    dynamicScreenSpaceErrorFactor: 4.0,
    dynamicScreenSpaceErrorHeightFalloff: 0.25,
  });
  // 将3DTileset加入图元层
  viewer.scene.primitives.add(tileset);

  //模型加载后需要对模型进行调整
  tileSet(tileset, longitude, latitude, height);

  //飞入模型位置
  viewer.flyTo(tileset); // , new Cesium.HeadingPitchRange(0, -0.45, 0)
}
// 利用translation对模型的经度、纬度、高度进行修改
function tileSet(tileset: any, longitude: any, latitude: any, height: any) {
  //3dtile模型的边界球体
  let boundingSphere = tileset.boundingSphere;
  //迪卡尔空间直角坐标=>地理坐标（弧度制）
  let cartographic_original = Cesium.Cartographic.fromCartesian(
    boundingSphere.center
  );
  //设置新的经度、纬度、高度
  let cartographic_offset = Cesium.Cartographic.fromDegrees(
    longitude,
    latitude,
    height
  );
  //地理坐标（弧度制）=>迪卡尔空间直角坐标
  let Cartesian3_original = Cesium.Cartesian3.fromRadians(
    cartographic_original.longitude,
    cartographic_original.latitude,
    cartographic_original.height
  );
  let Cartesian3_offset = Cesium.Cartesian3.fromRadians(
    cartographic_offset.longitude,
    cartographic_offset.latitude,
    cartographic_offset.height
  );
  //获得地面和offset的转换
  let translation = Cesium.Cartesian3.subtract(
    Cartesian3_offset,
    Cartesian3_original,
    new Cesium.Cartesian3()
  );
  //修改模型矩阵
  tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
}
onMounted(() => {
  initMap().then(() => {
    addPoint();
  });
});
</script>


<style lang="scss" scoped>
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
</style>